home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
EXPAND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
50KB
|
1,819 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#define GEN
#include "hdr.h"
#include "libhdr.h"
#include "vars.h"
#include "gvars.h"
#include "attr.h"
#include "slot.h"
#include "segment.h"
#include "setp.h"
#include "langp.h"
#include "initp.h"
#include "initobjp.h"
#include "dbxp.h"
#include "miscp.h"
#include "utilp.h"
#include "glibp.h"
#include "readp.h"
#include "libp.h"
#include "arithp.h"
#include "librp.h"
#include "gnodesp.h"
#include "gmiscp.h"
#include "gutilp.h"
#include "aggrp.h"
#include "chapp.h"
#include "smiscp.h"
#include "gmainp.h"
#include "expandp.h"
void expand(Node node) /*;expand*/
{
/*
* Expander
* Performs a set of semantic transformations on the tree
* in order to simplify the job for the code generator.
* Some semantic optimizations are performed too.
* IMPORTANT:
* expand must not be called twice on the same structure, as
* for some kinds of nodes, the format before expand is
* different from the format after expand. A special problem
* arises for aggregates, where already expanded structures
* (subaggregates) are part of a not yet expanded structure
* (assignment to enclosing structure) that must be expanded.
* a special node, as_expanded, is used to block double
* expansion in that case.
*/
Fortup ft1, ft2;
Tuple tup, tup1, tup2;
Symbolmap instance_map, type_map;
Node node1, node2, node3, node4;
Symbol sym1, sym2, sym3, sym4;
int nk, cboolean;
Const lv;
Unitdecl ud;
/* TBSL remove the following declarations */
Const lbd_1, ubd_1, lbd_2, ubd_2;
int ubd_1_val, ubd_2_val, lbd_1_val, lbd_2_val;
Tuple instantiation_code, ntup ;
#ifdef TRACE
if (debug_flag)
gen_trace_node("EXPAND", node);
#endif
#ifdef DEBUG
if (trapns>0 && N_SEQ(node)== trapns && N_UNIT(node) == trapnu) trapn(node);
#endif
switch N_KIND(node) {
case(as_insert):
N_SIDE(node) = FALSE;
FORTUP(node1 = (Node), N_LIST(node), ft1);
expand(node1);
N_SIDE(node) |= N_SIDE(node1);
ENDFORTUP(ft1);
node1 = N_AST1(node);
expand(node1);
N_SIDE(node) |= N_SIDE(node1);
break;
/* Chapter 3. Declarations and types*/
/*
*-----------------
* 3.1 Declarations
*/
case(as_declarations):
N_SIDE(node) = FALSE;
if (N_LIST(node) == (Tuple)0)
chaos("expand.c: as_declarations N_LIST null");
FORTUP(node1 = (Node), N_LIST(node), ft1);
expand(node1);
N_SIDE(node) |= N_SIDE(node1);
ENDFORTUP(ft1);
break;
/*
*------------------------------
* 3.2 Objects and named numbers
*/
case(as_obj_decl):
case(as_const_decl):
expand_decl(node);
break;
/*
*-----------------------
* 3.3 Types and subtypes
* 3.3.1
*/
case(as_type_decl):
expand_type(node);
break;
/* 3.3.2 */
case(as_subtype_decl):
expand_subtype(node);
break;
case(as_delayed_type):
sym1 = N_UNQ(N_AST1(node)); /* type name */
sym2 = N_UNQ(N_AST2(node)); /* parent name */
node1 = copy_node(node); /* delayed node */
if (NATURE(sym1) == na_subtype)
N_KIND(node1) = as_subtype_decl;
else
N_KIND(node1) = as_type_decl;
nk = emap_get(sym2);
tup = EMAP_VALUE;
if (!nk) /* emap_defined */
tup = tup_new1((char *) node1);
else
tup = tup_with(tup, (char *)node1);
/* EMAP(sym2) = (EMAP(sym2)?[]) with node1;*/
emap_put(sym2, (char *) tup);
delete_node(node);
break;
case(as_subtype_indic):
sym1 = N_UNQ(N_AST1(node)); /* type name */
N_SIDE(node) = (unsigned)CONTAINS_TASK(sym1);
node2 = N_AST2(node); /* expression */
expand(node2);
N_SIDE(node) |= N_SIDE(node2);
break;
/*
*-----------------
* 3.5 Scalar types
*/
case(as_digits):
expand(N_AST1(node)); /* precision node */
node2 = N_AST2(node); /* range node */
expand(node2);
N_SIDE(node) = N_SIDE(node2);
break;
case(as_delta):
expand(N_AST1(node)); /* precision node */
node2 = N_AST2(node); /* range node */
expand(node2);
N_SIDE(node) = N_SIDE(node2);
break;
case(as_subtype):
node2 = N_AST2(node);
expand(node2);
N_SIDE(node) = N_SIDE(node2);
/* Transmit tasks_declared: */
sym1 = N_UNQ(N_AST1(node)); /* type name */
/* N_TYPE(node) is parent type */
CONTAINS_TASK(sym1) = CONTAINS_TASK(N_TYPE(node));
break;
case(as_component_list):
node1 = N_AST1(node); /* invariant node */
FORTUP(node2 = (Node), N_LIST(node1), ft1);
expand(node2); /* field node */
ENDFORTUP(ft1);
expand(N_AST2(node)); /* variant node */
N_SIDE(node) = FALSE;
break;
case(as_simple_choice):
node1 = N_AST1(node); /* expression */
expand(node1);
N_SIDE(node) = N_SIDE(node1);
break;
case(as_incomplete_decl):
sym1 = N_UNQ(N_AST1(node)); /* type name */
CONTAINS_TASK(sym1) = (char *) TRUE; /* May be. Future will tell */
delete_node(node);
break;
/*
* Chapter 4. Names and expressions
*
*----------
* 4.1 Names
*/
case(as_range_choice):
node1 = N_AST1(node);
if (N_KIND(node1) == as_attribute) {
/* must be range. */
sym1 = N_TYPE(node1);
nk = (int)attribute_kind(node1) - ATTR_RANGE; /* 'T' or 'O'*/
attribute_kind(node1) = (char *) (nk + ATTR_FIRST);
N_AST2(node) = new_attribute_node(nk + ATTR_LAST,
N_AST2(node1), N_AST3(node1), sym1);
N_KIND(node) = as_range;
N_TYPE(node) = sym1;
expand(node);
}
else {
node2 = N_AST2(node1);
expand(node2);
N_SIDE(node) = N_SIDE(node2);
}
break;
case(as_range):
node1 = N_AST1(node); /* expression */
node2 = N_AST2(node); /* expression */
expand(node1);
expand(node2);
N_SIDE(node) = N_SIDE(node1) | N_SIDE(node2);
break;
case(as_constraint):
N_SIDE(node) = FALSE;
FORTUP(node1 = (Node), N_LIST(node), ft1);
if (N_KIND(node1) == as_choice_list) {
/* named discriminant constraints. Only need expression. */
node1 = N_AST2(node1) ;
}
expand(node1);
N_SIDE(node) |= N_SIDE(node1);
ENDFORTUP(ft1);
break;
case(as_index):
node1 = N_AST1(node) ; /* array node */
expand(node1);
N_SIDE(node) = N_SIDE(node1);
/* N_AST2(node) is a list of indices */
FORTUP(node2 = (Node), N_LIST(N_AST2(node)), ft1);
expand(node2); /* index */
N_SIDE(node) |= N_SIDE(node2);
ENDFORTUP(ft1);
break;
/*
* 4.1.2
*/
case(as_slice):
node2 = N_AST2(node) ; /* range node */
if (N_KIND(node2) == as_subtype) {
/* remove subtype */
node1 = N_AST2(node2); /* id node */
copy_attributes(node1, node2);
}
if (is_simple_name(node2)) {
/* type name replaced by range attribute */
/* SETL has OPT_NODE as third arg in next call. This is
* wrong - want to indicate first dimension.
* ds 9-8-85
*/
node2 = new_attribute_node(ATTR_T_RANGE, node2,
new_ivalue_node(int_const(1), symbol_integer), N_UNQ(node2));
N_AST2(node) = node2 ;
}
node1 = N_AST1(node) ; /* array node */
expand(node1);
N_SIDE(node) = N_SIDE(node1);
expand(node2); /* range node */
N_SIDE(node) |= N_SIDE(node2);
break;
case(as_field):
node2 = N_AST2(node) ; /* expression */
expand(node2);
N_SIDE(node) = N_SIDE(node2);
break;
case(as_selector):
case(as_all):
node1 = N_AST1(node) ; /* expression */
expand(node1);
N_SIDE(node) = N_SIDE(node1);
break;
/*
* 4.1.4
*/
case(as_attribute):
case(as_range_attribute):
expand_attr(node);
break;
/*
*-------------
* 4.2 Literals
*/
case(as_string_ivalue):
expand_string(node);
break;
case(as_int_literal):
/* TBSL(JC) This is a kludge */
N_KIND(node) = as_ivalue;
lv = adaval(symbol_integer, N_VAL(node));
if (adaval_overflow)
chaos("unable to convert integer literal");
else
N_VAL(node) = (char *) lv;
N_SIDE(node) = FALSE;
break;
/*
*---------------
* 4.3 Aggregates
*/
case(as_array_aggregate):
#ifdef DEFER
/* N_LIST assignmentnot needed in packed version DS 3-86 */
N_LIST(node) = (Tuple)0; /* Useless information removed */
#endif
expand_array_aggregate(node) ;
N_SIDE(node) = N_KIND(node) != as_array_ivalue;
/* TBSL